#include "LED.h"
#include "app_main.h"
#include "usart4.h"
#include "wifi.h"
#include "delay.h"

// 测试功能开关: 定义此宏则启用测试代码，注释掉则禁用
// #define TUYA_TEST_ENABLE

#ifdef TUYA_TEST_ENABLE
#include "test.h"
#endif

// ============ WiFi强制重置变量 ============
// 解决问题: WiFi模块使用缓存的旧Product Key，导致手机搜不到设备
// 方案: 握手后2秒发送0x04重置命令，强制模块清除缓存并重新初始化
static uint8_t wifi_reset_done = 0;      // 重置完成标志
static uint32_t reset_timer = 0;         // 重置延迟计时器
// =========================================

// ============ 定期数据上报变量 ============
static uint32_t upload_tick = 0;         // 数据上报计时器
#define UPLOAD_INTERVAL  10000            // 上报间隔: 约10秒(根据wifi_uart_service()频率调整)
// =========================================

/**
 * @brief 主应用程序 - 完全参照 data.txt 的标准交互流程实现
 * @param  无
 * @return 无
 * @note
 *   data.txt 中的正确交互流程:
 *   1. 心跳检测 (0x00)      ← WiFi模块发起，协议栈自动回复
 *   2. 查询产品信息 (0x01)  ← WiFi模块发起，协议栈自动回复
 *   3. 查询工作模式 (0x02)  ← WiFi模块发起，协议栈自动回复
 *   4. 设备状态信息 (0x03)  ← WiFi模块发起，协议栈自动回复
 *   5. 心跳维持 (0x00)      ← 协议栈定期处理
 *
 *   关键原则: 让协议栈自动处理所有握手和通信
 *   MCU代码的唯一职责: 初始化 + 循环处理
 */
void app_main(void)
{
    // 初始化WiFi模块通信 (UART4, 9600波特率)
    UART4_Init(9600);

    // 初始化涂鸦协议栈
    // 协议栈会自动处理所有握手过程 (心跳、产品信息查询、工作模式查询等)
    wifi_protocol_init();

#ifdef TUYA_TEST_ENABLE
    // 测试模式: 执行单元测试
    #include "delay.h"
    delay_ms(1000);
    Test_Tuya_Init();
    delay_ms(500);
    Test_Product_Info();
    delay_ms(500);
    Test_WiFi_State();
    delay_ms(500);
    Test_DP_Upload();
    delay_ms(500);
#endif

    // 主循环: 持续处理WiFi模块的通信
    // 协议栈会在这里自动完成:
    // - 接收并回复心跳检测
    // - 接收并回复产品信息查询
    // - 接收并回复工作模式查询
    // - 维持与WiFi模块的连接
    while(1)
    {
        // 这是唯一需要做的事: 处理协议通信
        // 所有复杂的握手逻辑都由协议栈内部自动完成
        wifi_uart_service();

        // ============ WiFi强制重置逻辑(手动配网重置) ============
        // 原理: 握手后2秒发送0x04重置命令，让WiFi模块清除缓存并重新初始化
        // 效果: 强制获取最新Product Key，解决手机搜不到设备的问题
        if (!wifi_reset_done) {
            if (reset_timer == 0) {
                reset_timer = 1;                // 第一次进入，开始计时
            } else if (reset_timer < 2000) {
                reset_timer++;                  // 继续计时
            } else if (reset_timer == 2000) {
                mcu_reset_wifi();               // 发送0x04重置指令
                wifi_reset_done = 1;            // 标记已重置，不再执行
            }
        }
        // =====================================================

#ifdef TUYA_TEST_ENABLE
        // 测试模式: LED闪烁表示运行中
        static uint32_t led_tick = 0;
        if(++led_tick > 100000)
        {
            LED_F;
            delay_ms(100);
            LED_O;
            delay_ms(100);
            led_tick = 0;
        }
#else
        // 正常运行模式: 在这里添加你的应用逻辑

#ifdef DATA_UPLOAD_DEMO_ENABLE
        // ============ 数据上传DEMO: 检测WiFi连接状态 ============
        // WiFi工作状态定义:
        // 0x00 - SmartConfig配置状态
        // 0x01 - AP配置状态
        // 0x02 - WiFi已配置但未连接路由器
        // 0x03 - WiFi已配置且连接到路由器
        // 0x04 - 已连接到路由器且连接到云端 ← 目标状态
        // 0x05 - 低功耗模式

        // 检查是否连接到云端
        if (wifi_work_state == 0x04 && !wifi_connected)
        {
            // 刚连接到云端，标记为已连接
            wifi_connected = 1;
        }

        // 如果连接到云端且还没上传过数据
        if (wifi_connected && !data_uploaded)
        {
            // 上报演示数据 (仅上报一次)

            // 示例1: 上报布尔型数据 - 电源开关
            // DPID_POWER 是你在protocol.c中定义的DP点ID
            mcu_dp_bool_update(1, TRUE);  // DP点1: 电源开 (TRUE/FALSE)

            // 示例2: 上报整数型数据 - 温度
            // value类型通常表示传感器数据，这里假设温度为25.5°C(255表示)
            mcu_dp_value_update(2, 255);  // DP点2: 温度值

            // 示例3: 上报枚举型数据 - 工作模式
            // enum类型通常用于状态选择，范围0-255
            mcu_dp_enum_update(3, 1);     // DP点3: 模式1

            // 标记数据已上传
            data_uploaded = 1;

            // 通过UART1调试打印上传状态(如果有UART1配置)
            #ifdef TUYA_PROTOCOL_DEBUG
            extern void UART1_Printf(char* fmt, ...);
            UART1_Printf("[DEMO] Data uploaded to cloud\r\n");
            #endif
        }

        // 如果WiFi断连，重置标志以便重新连接后再上传
        if (wifi_work_state != 0x04 && wifi_connected)
        {
            wifi_connected = 0;
            // 注意: 不重置data_uploaded，这样断连重连后不会再上传一次
            // 如果需要断连后重新上传，可以: data_uploaded = 0;
        }
#else
        // 如果禁用DEMO，可以在这里添加你的应用逻辑:
        // - 读取传感器数据
        // - 处理APP下发的控制命令 (通过 dp_download_handle)
        // - 定期更新设备状态 (通过 mcu_dp_*_update)
        // - 其他实时处理
#endif

#endif
    }
}
